/**
 * @desc: axios防抖节流请求封装
 * @params: {url: '', data: {}}
 * @return: Object
 */
import axios from 'axios';
import UTILS from '../utils/index';
import getSign from './sign.service';
import Config from '../config/index';

axios.defaults.withCredentials = true;

let DataServiceManager = {
  dataServices: {},
  add(id, dataService) {
    this.dataServices[id] = dataService;
  },
  abort(id) {
    if (this.dataServices[id]) {
      this.dataServices[id].cancelRequest();
    }
  },
  clear() {
    for (let i in this.dataServices) {
      if (Object.hasOwnProperty.call(this.dataServices, i)) {
        this.dataServices[i].cancelRequest();
        delete this.dataServices[i];
      }
    }
  }
};

// 请求配置
const DEFAULTCONFIG = {
  proxy: true, //是否需要通过代理请求数据
  mock: false, //是否使用mock拦截
  method: 'post', //method
  url: '', //url
  data: {}, //参数
  success: function () {}, // 成功的回调函数
  error: function () {}, // 错误的回调函数
  always: function () {} //完成的回调函数
};

const DEFAULTDATA = {
  isReduce: 1, //是否压缩的标识
  ver: 'v1.0.0', //版本号
  platForm: 'seeyii' //平台
};

const getRandomStr = () => {
  let str = 'qwertyuiopasdfghjklzxcvbnm';
  let result = [];
  for (let i = 0; i < 5; i++) {
    result.push(str.charAt(Math.floor(Math.random() * str.length)));
  }
  return 'ajax_' + result.join('');
};

/**
 * 拼接请求参数字符串
 * @param data
 */
const getParamsStr = function (data) {
  let result = [];
  for (let i in data) {
    if (Object.hasOwnProperty.call(data, i)) {
      result.push(i + '=' + data[i]);
    }
  }
  return result.join('&');
};

let LoginStatus = true;

class DataService {
  id = getRandomStr();
  configSource = {}; //存储起来的传入的请求配置
  config = {}; //配置
  loading = false; //请求状态标识
  cancel = null; //请求取消标识
  curAxios = null; //当前请求的axios对象
  timer = null; //防抖计时器
  debounceTimerLength = 300; //请求防抖时间时长
  timeoutLength = 90000; //超时时间，单位为ms

  successCallback = function () {};
  errorCallback = function () {};
  alwaysCallback = function () {};

  constructor(config) {
    let that = this;

    config = config || {};

    //创建当前请求所用的axios对象
    that.curAxios = axios.create({
      timeout: that.timeoutLength
    });

    if (config.id) {
      that.id = config.id;
    }

    if (!config.url || config.url.length === 0) {
      // debugger;
    }

    //初始化请求配置
    that.updateConfig(config);

    let CancelToken = axios.CancelToken;
    that.config.cancelToken = new CancelToken(function executor(c) {
      // executor 函数接收一个 cancel 函数作为参数
      that.cancel = c;
    });

    // 添加请求拦截器
    this.curAxios.interceptors.request.use(
      function (config) {
        // 在发送请求之前做些什么
        return config;
      },
      function (error) {
        that.loading = false;
        // 对请求错误做些什么
        return Promise.reject(error);
      }
    );

    // 添加响应拦截器
    this.curAxios.interceptors.response.use(
      function (response) {
        that.loading = false;
        // 对响应数据做点什么
        let result = response.data || {};
        let msg = result.msg || {};
        switch (msg.code) {
          case '10003': // 用户重复登录
          case '10006': // session失效或没有session
            DataServiceManager.clear();
            if (window.SEEYII_JC) {
              window.SEEYII_JC.$VRoute('login', {}, 'replace');
            }
            break;
          default:
            break;
        }

        return result;
      },
      function (error) {
        that.loading = false;
        if (error.response && error.response.status === 808) {
          if (window.SEEYII_JC) {
            window.SEEYII_JC.$VRoute('login', {}, 'replace');
          }
        }
        // 对响应错误做点什么
        return Promise.reject(error);
      }
    );

    DataServiceManager.add(that.id, that);
  }

  // 处理传参
  updateConfig(cfg) {
    this.configSource = Object.assign({}, this.configSource, cfg);
    let tempConfig = Object.assign({}, DEFAULTCONFIG, this.configSource);
    this.config = {};
    this.config['method'] = tempConfig['method'];

    //重置请求防抖间隔时长
    if (tempConfig.debounceTimerLength !== undefined) {
      this.debounceTimerLength = tempConfig.debounceTimerLength;
    }
    //初始化请求成功回调函数
    if (tempConfig.success) {
      this.successCallback = tempConfig.success;
    }
    //初始化请求失败回调函数
    if (tempConfig.error) {
      this.errorCallback = tempConfig.error;
    }
    //初始化请求不管成功与否一定会执行的函数
    if (tempConfig.always) {
      this.alwaysCallback = tempConfig.always;
    }
    if (tempConfig.proxy && !tempConfig.mock) {
      //通过代理请求数据接口数据
      //给 data 添加请求默认参数
      let tempData = Object.assign(
        {},
        DEFAULTDATA,
        Config.globalData,
        tempConfig.data
      );
      //添加时间戳
      tempData['timestamp'] = new Date().getTime();
      //添加sign值
      tempData = getSign(tempData);
      //提取请求数据接口的URL
      let dataUrl = tempConfig.url,
        //序列化请求的参数
        dataParams = getParamsStr(tempData);
      //重整请求参数
      this.config.data = Object.assign({}, DEFAULTDATA, Config.globalData, {
        url: dataUrl,
        params: dataParams,
        pageType: tempData.pageType || 0
      });
      //拼接请求数据接口的代理接口的URL
      let proxyType =
        tempConfig.url && tempConfig.url.indexOf('bidding/') > -1
          ? Config.inters.proxyInters.proxyBidding
          : tempConfig.url && tempConfig.url.indexOf('.dhtml') > -1
          ? Config.inters.proxyInters.proxyOld
          : Config.inters.proxyInters.proxyRights;

      this.config['url'] = Config.baseUrl + proxyType;
    } else if (!tempConfig.proxy && !tempConfig.mock) {
      //直接请求代理上的接口返回的数据
      //拼接请求接口的完整的URL
      this.config['url'] = Config.baseUrl + tempConfig.url;
      //添加请求接口所需的默认参数
      this.config.data = Object.assign(
        {},
        DEFAULTDATA,
        Config.globalData,
        tempConfig.data
      );
    } else {
      let tempData = Object.assign(
        {},
        DEFAULTDATA,
        Config.globalData,
        tempConfig.data
      );
      //添加时间戳
      tempData['timestamp'] = new Date().getTime();
      //添加sign值
      tempData = getSign(tempData);
      //提取请求数据接口的URL
      //序列化请求的参数
      let dataParams = getParamsStr(tempData);
      //重整请求参数
      this.config.data = Object.assign({}, DEFAULTDATA, Config.globalData, {
        params: dataParams
      });
      this.config['url'] = tempConfig.url;
    }
    //添加时间戳
    this.config.data['timestamp'] = new Date().getTime();
    //计算sign值
    this.config.data = getSign(this.config);
    //序列化参数
    this.config.data = UTILS.serializeData(this.config.data);
  }

  getRequest() {
    let that = this;
    //更新请求状态标识
    that.loading = true;
    //初始化可取消请求控制器
    that.cancel = null;
    that._updateCancelToken();
    //保存当前请求
    return that.curAxios.request(this.config);
  }

  /**
   * 直接发起请求
   */
  request() {
    let that = this;
    // 用户登录状态为未登录的时候不发起请求
    if (!LoginStatus) {
      return;
    }
    //更新请求状态标识
    that.loading = true;
    //初始化可取消请求控制器
    that.cancel = null;
    that._updateCancelToken();
    //保存当前请求
    that.curAxios
      .request(that.config)
      .then(function (data) {
        that.successCallback(data);
      })
      .catch(function () {
        that.errorCallback(arguments);
      })
      .finally(function () {
        that.alwaysCallback(arguments);
      });
  }

  /**
   * 发起防抖请求
   */
  debounceRequest() {
    let that = this;

    that.cancelRequest();
    that.timer = null;

    that.timer = window.setTimeout(function () {
      //更新请求状态标识
      that.loading = true;
      //初始化可取消请求控制器
      that.cancel = null;
      that._updateCancelToken();
      //开始请求
      that.curAxios
        .request(that.config)
        .then(function (data) {
          that.successCallback(data);
        })
        .catch(function () {
          that.errorCallback(arguments);
        })
        .finally(function () {
          that.alwaysCallback(arguments);
        });
    }, that.debounceTimerLength);
  }

  // 取消请求
  cancelRequest() {
    if (this.timer) {
      window.clearTimeout(this.timer);
    }
    if (this.cancel) {
      this.cancel();
    }
  }

  _updateCancelToken() {
    let that = this;

    let CancelToken = axios.CancelToken;
    that.id = new Date().getTime();
    that.config.cancelToken = new CancelToken(function executor(c) {
      // executor 函数接收一个 cancel 函数作为参数
      that.cancel = c;
    });
  }
}
/**
 * 判断全称是否是公司
 * @param cname
 * @return {boolean}
 */
const ifCompany = function (cname) {
  let result = false;
  if (/[;；,，、:：\s/|]/gi.test(cname) === false && cname) {
    let identifying = [
      '公司',
      '基金',
      '管理计划',
      '银行',
      '集团',
      '(有限合伙)',
      '（有限合伙）',
      '医院',
      '大学',
      '学院',
      '有限合伙）'
    ];
    for (let i = 0; i < identifying.length; i++) {
      let l = identifying[i].length;
      let str = cname.substring(cname.length - l);
      if (str === identifying[i]) {
        result = true;
      }
    }
  }
  return result;
};
// 保留两位小数
const keepTwoDecimal = function (x) {
  let f = parseFloat(x);
  if (isNaN(f)) {
    return '--';
  }
  f = f.toFixed(2);
  return f;
};
export default {
  axios,
  DataService,
  DataServiceManager,
  ifCompany,
  keepTwoDecimal
};
